﻿using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
using System;

namespace PFD
{

    public interface IArrayElementModifier<T>
    {
        bool IsDirty { get; }
        void ResetDirtyFlag();
        T this[long nNumber]
        {
            get;
            set;
        }
    }

    [FlagsAttribute]
    public enum VertexElementType : short
    {
        Position=0,
        Color=1,
        Normal=2,
        TextureSet1Coordinates=4,
        TextureSet2Coordinates=8
    }

    [FlagsAttribute]
    public enum VertexElementDimension :long
    {
        X,
        Y,
        Z,
        Alpha,
        Red,
        Green,
        Blue,
        Nx,
        Ny,
        Nz,
        U1,
        V1,
        U2,
        V2
    }

    public enum SHADE_MODE
    {
        Flat
    }

    public enum DRAW_MODE
    {
        TriangleFan,
        TriangleStrip
    }

    public interface IVertexBuffer  : IDisposable, IArrayElementModifier<float>
    {
        long GetElementBufferIndex(VertexElementDimension ved, long nidx);

        bool AddVectors(float[] vertex);
        bool AddColors(float[] colors);
        bool AddNormals(float[] normals);
        bool AddTexCoords(uint n, float[] texcoords);

        bool ColorsEnabled { get; set; }
        bool NormalsEnabled { get; set; }
        bool TextureSet1Enabled { get; set; }
        bool TextureSet2Enabled { get; set; }

        float this[long vertexno, VertexElementDimension element]
        {
            get;
            set;
        }

        uint NumberOfVertices { get; }
        uint stride { get; }

        bool RealizeVertexBuffer(IRenderDevice rd, bool AllowSinglepassMultitexture, uint singlePassTextureNum);
    }

    public enum RenderTextureProviderState
    {
        BlendingEnabled
    }

    public interface IRenderTextureProvider
    {
        IRenderTexture this[uint index] { get; }
        bool this[uint index, RenderTextureProviderState state] {get;}
        uint Count { get; }
    }

    public interface IRenderTexture : IDisposable
    {
        uint Name
        {
            get;
        }
    }

    public interface IRenderDevice : IDisposable
    {
        bool Initialize(Form f);

        bool SetViewport(Rectangle r);

        bool SetOrthographicProjection(float left, float right, float top, float bottom, float near, float far);


        bool EnableTexturing(bool bEnable);
        bool EnableShading(SHADE_MODE sm);
        bool EnableDepthTest(bool bEnable);
        bool EnableDithering(bool bEnable);
        bool EnableBlending(bool bEnable);

        IVertexBuffer CreateVertexBuffer(uint numVertices, VertexElementType vet);

        bool BeginScene();
        bool Clear(bool bClrColor, bool bClrDepth);
        bool DrawString(string s, float x, float y, float z);
        bool EndScene();
        bool SwapBuffers();

        bool ResetObjectMatrix();
        bool TranslateObject(float x, float y, float z);
        bool RotateObject(float angle, float x, float y, float z);
        bool ScaleObject(float x, float y, float z);

        IRenderTexture CreateTexture(string path, bool bIsTransparent);

        bool DrawObject(DRAW_MODE dm, IVertexBuffer ivb, IRenderTextureProvider textureProvider);
    }

    public interface IGlobalPoolContainer
    {
        IRenderTexture GetTexture(string szTexturename);
    }

    public interface ISystemVariable<T>
    {
        string Name { get; set; }
        T Value { get; set; }

        void NotifyValueChange();
    }

    public interface ISystemVarConnector<T>
    {
        void DoUpdate(T newVal);
    }

    /// <summary>
    /// This interface represents an external extension interface
    /// </summary>
    public interface IExtensionComponent
    {
        void Initialize(IExtensionFactory factory);
        void GetComponentName([Out] StringBuilder szName);
    }

    public interface IExtensionFactory
    {
        IGlobalPoolContainer GetGlobalPoolContainer();

        bool RegisterSystemVariable_bool(string szVariableName, ISystemVarConnector<bool> boolVar);
        bool RegisterSystemVariable_float(string szVariableName, ISystemVarConnector<float> floatVar);

        bool RegisterSystemVariable_boolobject(string szVariableName, ISystemVariable<bool> boolVarObj);
        bool RegisterSystemVariable_floatobject(string szVariableName, ISystemVariable<float> floatVarObj);

        IEnumerator<ISystemVarConnector<bool>> GetSystemVariable_bool(string szVariableName);
        ISystemVariable<bool> GetSystemVariable_boolobject(string szVariableName);
        IEnumerator<ISystemVarConnector<float>> GetSystemVariable_float(string szVariableName);
        ISystemVariable<float> GetSystemVariable_floatobject(string szVariableName);
    }
}

